package com.wnhoo.smartfishtank.ui;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.Point;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.ImageView;

import com.wnhoo.smartfishtank.R;


/**
 * Created by Administrator on 2015/10/28.
 */
public class Color_picker extends ImageView{
    private static Bitmap imageOriginal, imageScaled;
    private static Matrix matrix;

    private ImageView dialer;
    private int dialerHeight, dialerWidth,startx,starty;

    private GestureDetector detector;
    private Context context;
    // needed for detecting the inversed rotations
    private boolean[] quadrantTouched;

    private boolean allowRotating;
    private int translateX,translateY;
    private OnColorChangedListener listener;
    private double x,y;
    private Point mRockPosition = new Point();
    private int j;
    private int position;

    public Color_picker(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        initView();
    }
    public void setOnColorChangedListenner(OnColorChangedListener listener) {
        this.listener = listener;

    }
    private void initView() {
        if(imageOriginal==null){
            imageOriginal = BitmapFactory.decodeResource(getResources(),R.drawable.color_picker_touch_bg2);
        }
        // initialize the matrix only once
        if (matrix == null) {
            matrix = new Matrix();
        } else {
            // not needed, you can also post the matrix immediately to restore the old state
            matrix.reset();
        }

        detector = new GestureDetector(context, new MyGestureDetector());

        // there is no 0th quadrant, to keep it simple the first value gets ignored
        quadrantTouched = new boolean[] { false, false, false, false, false };

        allowRotating = true;

        dialer = (ImageView) findViewById(R.id.imageView_ring_color);
        dialer.setOnTouchListener(new MyOnTouchListener());
        dialer.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

            @Override
            public void onGlobalLayout() {
                // method called more than once, but the values only need to be initialized one time
                if (dialerHeight == 0 || dialerWidth == 0) {
                    dialerHeight = (int) getResources().getDimension(R.dimen.circel_width);
                    dialerWidth =(int) getResources().getDimension(R.dimen.circel_width);
                    // resize
                    Matrix resize = new Matrix();

                    resize.postScale((float) Math.min(dialerWidth, dialerHeight) / (float) imageOriginal.getWidth(), (float) Math.min(dialerWidth, dialerHeight) / (float) imageOriginal.getHeight());
                    imageScaled = Bitmap.createBitmap(imageOriginal, 0, 0, imageOriginal.getWidth(), imageOriginal.getHeight(), resize, false);

                    // translate to the image view's center
                    translateX = dialerWidth / 2 - imageScaled.getWidth() / 2;
                    translateY = dialerHeight / 2 - imageScaled.getHeight() / 2;
                    matrix.postTranslate(translateX, translateY);


                    dialer.setImageBitmap(imageScaled);
                    dialer.setImageMatrix(matrix);
                }
            }
        });
    }
    private class MyOnTouchListener implements OnTouchListener {

        private double startAngle;

        @Override
        public boolean onTouch(View v, MotionEvent event) {

            switch (event.getAction()) {

                case MotionEvent.ACTION_DOWN:
                    // reset the touched quadrants
                    for (int i = 0; i < quadrantTouched.length; i++) {
                        quadrantTouched[i] = false;
                    }

                    allowRotating = false;

                    startAngle = getAngle(event.getX(), event.getY());



                    break;

                case MotionEvent.ACTION_MOVE:
                    double currentAngle = getAngle(event.getX(), event.getY());

                    rotateDialer((float) (startAngle - currentAngle));
                    mRockPosition.set(imageScaled.getWidth() / 2, 10);
                    startAngle = currentAngle;
                    Matrix matrix1 = new Matrix();
                    //想知道经过矩阵运算后的图片上某个坐标对应没有matrix运算前的坐标，得到当前矩阵的逆矩阵
                    matrix.invert(matrix1);
                    float[] f = new float[]{imageScaled.getWidth()/2,10};
                    //根据逆矩阵得到之前图片上的某个坐标
                    matrix1.mapPoints(f);
                    j  = imageScaled.getPixel((int)f[0],(int)f[1]);
                    if(position%4==0){
                        if(listener!=null)listener.onColorChanging(j);
                    }
                    position++;
                    break;

                case MotionEvent.ACTION_UP:
                    position =0;
                    if(listener!=null)listener.onColorChanging(j);
                    allowRotating = true;
                    break;
            }

            // set the touched quadrant to true
            quadrantTouched[getQuadrant(event.getX() - (dialerWidth / 2), dialerHeight - event.getY() - (dialerHeight / 2))] = true;

            detector.onTouchEvent(event);

            DisplayMetrics dm = new DisplayMetrics();
//          getWindowManager().getDefaultDisplay().getMetrics(dm);

            int widthPixels = dm.widthPixels;
            int heightPixels = dm.heightPixels;


            return true;
        }
    }
    private class MyGestureDetector extends GestureDetector.SimpleOnGestureListener {
//		@Override
//		public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
//
//			// get the quadrant of the start and the end of the fling
//			int q1 = getQuadrant(e1.getX() - (dialerWidth / 2), dialerHeight - e1.getY() - (dialerHeight / 2));
//			int q2 = getQuadrant(e2.getX() - (dialerWidth / 2), dialerHeight - e2.getY() - (dialerHeight / 2));
//
//			// the inversed rotations
//			if ((q1 == 2 && q2 == 2 && Math.abs(velocityX) < Math.abs(velocityY))
//					|| (q1 == 3 && q2 == 3)
//					|| (q1 == 1 && q2 == 3)
//					|| (q1 == 4 && q2 == 4 && Math.abs(velocityX) > Math.abs(velocityY))
//					|| ((q1 == 2 && q2 == 3) || (q1 == 3 && q2 == 2))
//					|| ((q1 == 3 && q2 == 4) || (q1 == 4 && q2 == 3))
//					|| (q1 == 2 && q2 == 4 && quadrantTouched[3])
//					|| (q1 == 4 && q2 == 2 && quadrantTouched[3])) {
//
//				dialer.post(new FlingRunnable(-1 * (velocityX + velocityY)));
//			} else {
//				// the normal rotation
//				dialer.post(new FlingRunnable(velocityX + velocityY));
//			}
//
//			return true;
//		}
    }
    private double getAngle(double xTouch, double yTouch) {
        x = xTouch - (dialerWidth / 2d);


         y = dialerHeight - yTouch - (dialerHeight / 2d);

        switch (getQuadrant(x, y)) {
            case 1:
                return Math.asin(y / Math.hypot(x, y)) * 180 / Math.PI;

            case 2:
            case 3:
                return 180 - (Math.asin(y / Math.hypot(x, y)) * 180 / Math.PI);

            case 4:
                return 360 + Math.asin(y / Math.hypot(x, y)) * 180 / Math.PI;

            default:
                // ignore, does not happen
                return 0;

        }

    }
    private static int getQuadrant(double x, double y) {
        if (x >= 0) {
            return y >= 0 ? 1 : 4;
        } else {
            return y >= 0 ? 2 : 3;
        }
    }
    private void rotateDialer(float degrees) {
        matrix.postRotate(degrees, dialerWidth / 2, dialerHeight / 2);

        dialer.setImageMatrix(matrix);
//        int i = imageOriginal.getPixel(translateX,translateY);
//        Log.i("i", "====" + i);
    }
    /**
     * A {@link Runnable} for animating the the dialer's fling.
     */
    private class FlingRunnable implements Runnable {

        private float velocity;

        public FlingRunnable(float velocity) {
            this.velocity = velocity;
        }

        @Override
        public void run() {
            if (Math.abs(velocity) > 5 && allowRotating) {
                rotateDialer(velocity / 75);
                velocity /= 1.0666F;

                // post this instance again
                dialer.post(this);
            }
        }
    }
    // 内部接口
    public interface OnColorChangedListener {
//        void onColorChanged(int color);
        void onColorChanging(int color);

    }
}
